Imports MatrixDataStructures
Public Class DWICorrection
    Dim CompositeDisplay As New MainForm
    Dim binarymap As Matrix3DInt16
    Dim a0 As Matrix3DInt16

    Public Sub New()
        ' This call is required by the Windows Form Designer.
        InitializeComponent()

        CompositeDisplay.Refresh()
        If CompositeDisplay.Visible = False Then CompositeDisplay.Visible = True
        CompositeDisplay.Size = PictureBox4.Size
        Dim temp As Point = Me.PointToScreen(PictureBox4.Location)
        temp.Y += Me.SplitContainer1.Panel1.Height + 5
        CompositeDisplay.Location = temp
        AddHandler CompositeDisplay.CurrentSlice, AddressOf CurrentSliceInformation
        AddHandler CompositeDisplay.MouseMovedOnImage, AddressOf donothing

        CompositeDisplay.OpenFile(New SingleVolume(New Matrix3DInt16(FormMain.DiffusionVolume.Matrix.ExtractVolume(0)), FormMain.DiffusionVolume.FOV, FormMain.DiffusionVolume.Center), "A0", True, False)
        a0 = New Matrix3DInt16(FormMain.DiffusionVolume.Matrix.ExtractVolume(0))
        Button8.BackColor = Color.Wheat
    End Sub

#Region "Form Events"

    Private Sub DTIDirectionMap_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
        If Me.CompositeDisplay IsNot Nothing Then CompositeDisplay.Close()
    End Sub
    Private Sub CompositeViewerForm_GotFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.GotFocus
        CompositeDisplay.Focus()
        CompositeDisplay.BringToFront()
        If CompositeDisplay.Visible = False Then CompositeDisplay.Visible = True
        CompositeDisplay.Size = PictureBox4.Size
        Dim temp As Point = Me.PointToScreen(PictureBox4.Location)
        temp.Y += Me.SplitContainer1.Panel1.Height + 5
        CompositeDisplay.Location = temp
        AddHandler CompositeDisplay.MouseMovedOnImage, AddressOf donothing
        AddHandler CompositeDisplay.CurrentSlice, AddressOf CurrentSliceInformation
    End Sub

    Sub donothing(ByVal sender As Object, ByVal e As EventArgs)

    End Sub
    Public Function GetFirstBit(ByVal Val As MainForm.DisplayType) As String
        Select Case Val
            Case MainForm.DisplayType.Coronal
                Return "c"
            Case MainForm.DisplayType.Sagittal
                Return "s"
            Case MainForm.DisplayType.Transverse
                Return "t"
            Case Else
                Return "t"
        End Select
    End Function

    Public CurrentActiveDisplay As MainForm.DisplayType = MainForm.DisplayType.Coronal
    Public CurrentActiveSlice As Integer
    Public Sub CurrentSliceInformation(ByVal sender As Object, ByVal e As EventArgs)
        Dim sliceinfo As String = CType(sender, String)
        Select Case Mid(sliceinfo, 1, 1)
            Case "t"
                CurrentActiveDisplay = MainForm.DisplayType.Transverse
            Case "c"
                CurrentActiveDisplay = MainForm.DisplayType.Coronal
            Case "s"
                CurrentActiveDisplay = MainForm.DisplayType.Sagittal
        End Select
        CurrentActiveSlice = CInt(Mid(sliceinfo, 2, sliceinfo.Length - 1))
    End Sub

    Dim WithEvents Composite As MainForm




    Private Sub CompositeViewerForm_Move(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Move
        CompositeDisplay.Focus()
        If CompositeDisplay.Visible = False Then CompositeDisplay.Visible = True
        CompositeDisplay.Size = PictureBox4.Size
        Dim temp As Point = Me.PointToScreen(PictureBox4.Location)
        temp.Y += Me.SplitContainer1.Panel1.Height + 5
        CompositeDisplay.Location = temp
        '    AddHandler CompositeDisplay.LostFocus, AddressOf CloseCompositeDisplay
        AddHandler CompositeDisplay.CurrentSlice, AddressOf CurrentSliceInformation
    End Sub

    Private Sub DTIDirectionMap_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
        CompositeDisplay.Focus()
        If CompositeDisplay.Visible = False Then CompositeDisplay.Visible = True
        CompositeDisplay.Size = PictureBox4.Size
        Dim temp As Point = Me.PointToScreen(PictureBox4.Location)
        temp.Y += Me.SplitContainer1.Panel1.Height + 5
        CompositeDisplay.Location = temp
        '    AddHandler CompositeDisplay.LostFocus, AddressOf CloseCompositeDisplay
        AddHandler CompositeDisplay.CurrentSlice, AddressOf CurrentSliceInformation
    End Sub

    Private Sub CompositeViewerForm_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Resize
        ' CompositeDisplay.MdiParent = Me
        CompositeDisplay.Focus()
        CompositeDisplay.BringToFront()
        If CompositeDisplay.Visible = False Then CompositeDisplay.Visible = True
        CompositeDisplay.Size = PictureBox4.Size
        Dim temp As Point = Me.PointToScreen(PictureBox4.Location)
        temp.Y += Me.SplitContainer1.Panel1.Height + 5
        CompositeDisplay.Location = temp
        '    AddHandler CompositeDisplay.LostFocus, AddressOf CloseCompositeDisplay
        AddHandler CompositeDisplay.CurrentSlice, AddressOf CurrentSliceInformation
    End Sub

    Private Sub CompositeViewerForm_ResizeEnd(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.ResizeEnd
        ' CompositeDisplay.MdiParent = Me
        CompositeDisplay.Focus()
        CompositeDisplay.BringToFront()
        If CompositeDisplay.Visible = False Then CompositeDisplay.Visible = True
        CompositeDisplay.Size = PictureBox4.Size
        Dim temp As Point = Me.PointToScreen(PictureBox4.Location)
        temp.Y += Me.SplitContainer1.Panel1.Height + 5
        CompositeDisplay.Location = temp
        '    AddHandler CompositeDisplay.LostFocus, AddressOf CloseCompositeDisplay
        AddHandler CompositeDisplay.CurrentSlice, AddressOf CurrentSliceInformation
    End Sub

    Private Sub CompositeViewerForm_SizeChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.SizeChanged
        ' CompositeDisplay.MdiParent = Me
        CompositeDisplay.Focus()
        CompositeDisplay.BringToFront()
        If CompositeDisplay.Visible = False Then CompositeDisplay.Visible = True
        CompositeDisplay.Size = PictureBox4.Size
        Dim temp As Point = Me.PointToScreen(PictureBox4.Location)
        temp.Y += Me.SplitContainer1.Panel1.Height + 5
        CompositeDisplay.Location = temp
        '    AddHandler CompositeDisplay.LostFocus, AddressOf CloseCompositeDisplay
        AddHandler CompositeDisplay.CurrentSlice, AddressOf CurrentSliceInformation
    End Sub

    Private Sub CompositeViewerForm_Validated(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Validated
        ' CompositeDisplay.MdiParent = Me
        CompositeDisplay.Focus()
        CompositeDisplay.BringToFront()
        If CompositeDisplay.Visible = False Then CompositeDisplay.Visible = True
        CompositeDisplay.Size = PictureBox4.Size
        Dim temp As Point = Me.PointToScreen(PictureBox4.Location)
        temp.Y += Me.SplitContainer1.Panel1.Height + 5
        CompositeDisplay.Location = temp
        '    AddHandler CompositeDisplay.LostFocus, AddressOf CloseCompositeDisplay
        AddHandler CompositeDisplay.CurrentSlice, AddressOf CurrentSliceInformation
    End Sub

#End Region

#Region "Morphology Filters"
    Public ElementSize As Integer = 1

    Function Erode(ByVal binarymap As Matrix3DInt16) As Matrix3DInt16
        Dim temp As New Matrix3DInt16(binarymap.x, binarymap.y, binarymap.z)
        Dim val As Int16 = 0
        For i As Integer = ElementSize To binarymap.x - ElementSize - 1
            For j As Integer = ElementSize To binarymap.y - ElementSize - 1
                For k As Integer = ElementSize To binarymap.z - ElementSize - 1
                    'for each voxel
                    val = binarymap(i, j, k)
                    For a As Integer = -ElementSize To ElementSize
                        For b As Integer = -ElementSize To ElementSize
                            For c As Integer = -ElementSize To ElementSize
                                ' in the structuring element
                                val = Math.Min(val, binarymap(i + a, j + b, k + c))
                            Next
                        Next
                    Next
                    temp(i, j, k) = val
                Next
            Next
        Next
        Return temp
    End Function
    Function Dilate(ByVal binarymap As Matrix3DInt16) As Matrix3DInt16
        Dim temp As New Matrix3DInt16(binarymap.x, binarymap.y, binarymap.z)
        Dim val As Int16 = 0
        For i As Integer = ElementSize To binarymap.x - ElementSize - 1
            For j As Integer = ElementSize To binarymap.y - ElementSize - 1
                For k As Integer = ElementSize To binarymap.z - ElementSize - 1
                    'for each voxel
                    val = binarymap(i, j, k)
                    For a As Integer = -ElementSize To ElementSize
                        For b As Integer = -ElementSize To ElementSize
                            For c As Integer = -ElementSize To ElementSize
                                ' in the structuring element
                                val = Math.Max(val, binarymap(i + a, j + b, k + c))
                            Next
                        Next
                    Next
                    temp(i, j, k) = val
                Next
            Next
        Next
        Return temp
    End Function

    Function OpeningFilter(ByVal binarymap As Matrix3DInt16) As Matrix3DInt16
        binarymap = Erode(binarymap)
        binarymap = Dilate(binarymap)
        Return binarymap
    End Function
    Function ClosingFilter(ByVal binarymap As Matrix3DInt16) As Matrix3DInt16
        binarymap = Dilate(binarymap)
        binarymap = Erode(binarymap)
        Return binarymap
    End Function
#End Region

    Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
        For i As Integer = 0 To binarymap.x - 1
            For j As Integer = 0 To binarymap.y - 1
                For k As Integer = 0 To binarymap.z - 1
                    For l As Integer = 0 To FormMain.DiffusionVolume.Matrix.l - 1
                        FormMain.DiffusionVolume.Matrix.data(i, j, k, l) *= binarymap(i, j, k)
                    Next

                Next
            Next
        Next
        
        FormMain.DiffusionDisplay.OpenFile(New SingleVolume(New Matrix3DInt16(FormMain.DiffusionVolume.Matrix.ExtractVolume(0)), FormMain.DiffusionVolume.FOV, FormMain.DiffusionVolume.Center), "Filtered A0", True, False)
        If CompositeDisplay IsNot Nothing Then CompositeDisplay.Close()
        Me.Close()
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        binarymap = OpeningFilter(binarymap)
        CompositeDisplay.OpenFile(New SingleVolume(binarymap, FormMain.DiffusionVolume.FOV, FormMain.DiffusionVolume.Center), "Map", True, False)
        Button2.BackColor = Button1.BackColor
        Button1.BackColor = Color.Wheat
    End Sub

    Private Sub Button6_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button6.Click
        binarymap = Dilate(binarymap)
        CompositeDisplay.OpenFile(New SingleVolume(binarymap, FormMain.DiffusionVolume.FOV, FormMain.DiffusionVolume.Center), "Map", True, False)
    End Sub

    Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click
        Dim a As String = InputBox.Show("Enter new Structuring Element Size", "Element", "1").Text
        Dim b As Int16 = 0
        If Int16.TryParse(a, b) = True Then
            Me.ElementSize = b
        End If
    End Sub

    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        binarymap = Erode(binarymap)
        CompositeDisplay.OpenFile(New SingleVolume(binarymap, FormMain.DiffusionVolume.FOV, FormMain.DiffusionVolume.Center), "Map", True, False)

    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        binarymap = ClosingFilter(binarymap)
        CompositeDisplay.OpenFile(New SingleVolume(binarymap, FormMain.DiffusionVolume.FOV, FormMain.DiffusionVolume.Center), "Map", True, False)
        Button1.BackColor = Button4.BackColor
        Button4.BackColor = Color.Wheat
    End Sub

    Private Sub DTIDirectionMap_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

    End Sub

    Private Sub Button8_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button8.Click
        'gamma
        Dim reversible As Boolean = True
        If MsgBox("Reversible?", MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then reversible = True Else reversible = False
        Dim temp As Double = CDbl((InputBox.Show("Enter new Gamma", "Gamma", "2.5")).Text)
        binarymap = New Matrix3DInt16(FormMain.DiffusionVolume.Matrix.i, FormMain.DiffusionVolume.Matrix.j, FormMain.DiffusionVolume.Matrix.k)
        Dim tempm As Matrix3DInt16 = New Matrix3DInt16(FormMain.DiffusionVolume.Matrix.i, FormMain.DiffusionVolume.Matrix.j, FormMain.DiffusionVolume.Matrix.k)
        For i As Integer = 0 To binarymap.x - 1
            For j As Integer = 0 To binarymap.y - 1
                For k As Integer = 0 To binarymap.z - 1
                    If FormMain.DiffusionVolume.Matrix.data(i, j, k, 0) > temp Then
                        If reversible Then
                            tempm(i, j, k) = CShort(FormMain.DiffusionVolume.Matrix.data(i, j, k, 0) ^ (1 / temp))
                        Else
                            a0(i, j, k) = CShort(FormMain.DiffusionVolume.Matrix.data(i, j, k, 0) ^ (1 / temp))
                        End If
                    End If
                Next
            Next
        Next
        If reversible Then CompositeDisplay.OpenFile(New SingleVolume(tempm, FormMain.DiffusionVolume.FOV, FormMain.DiffusionVolume.Center), "Temporary", True, True) Else CompositeDisplay.OpenFile(New SingleVolume(a0, FormMain.DiffusionVolume.FOV, FormMain.DiffusionVolume.Center), "Modified A0", True, False)
        Button8.BackColor = Button7.BackColor
        Button7.BackColor = Color.Wheat
    End Sub

    Private Sub Button7_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button7.Click
        'threshold
        Dim reversible As Boolean = True
        If MsgBox("Reversible?", MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then reversible = True Else reversible = False
        Dim temp As Integer = CInt(InputBox.Show("Enter Threshold", "Threshold", "5").Text)
        binarymap = New Matrix3DInt16(FormMain.DiffusionVolume.Matrix.i, FormMain.DiffusionVolume.Matrix.j, FormMain.DiffusionVolume.Matrix.k)
        Dim tempm As Matrix3DInt16 = New Matrix3DInt16(FormMain.DiffusionVolume.Matrix.i, FormMain.DiffusionVolume.Matrix.j, FormMain.DiffusionVolume.Matrix.k)
        For i As Integer = 0 To binarymap.x - 1
            For j As Integer = 0 To binarymap.y - 1
                For k As Integer = 0 To binarymap.z - 1
                    If a0(i, j, k) > temp Then
                        If reversible Then
                            tempm(i, j, k) = 1
                        Else
                            binarymap(i, j, k) = 1
                        End If
                    End If
                Next
            Next
        Next
        If reversible Then CompositeDisplay.OpenFile(New SingleVolume(tempm, FormMain.DiffusionVolume.FOV, FormMain.DiffusionVolume.Center), "Temporary", True, True) Else CompositeDisplay.OpenFile(New SingleVolume(binarymap, FormMain.DiffusionVolume.FOV, FormMain.DiffusionVolume.Center), "Map", True, False)
        Button7.BackColor = Button2.BackColor
        Button2.BackColor = Color.Wheat
    End Sub

End Class
